// class 定义类型
// class 关键字是一个语法糖，是函数的另一个写法。
// 类型是对象的模板，通过 new 运算符可以创建无数对象！

// TS 中增加了对于访问修饰符的支持，可以使用 public、private、protected 来修饰属性或方法
// public 修饰的属性或方法，可以在任何地方被访问
// private 修饰的属性或方法，只能在类内部被访问
// protected 修饰的属性或方法，只能在类内部和子类中被访问
// readonly 修饰的属性，只能在构造函数中被初始化，之后不能被修改

class Database {
  public static name = "unknow";
  protected readonly url: string;
  constructor(url: string) {
    this.url = url;
  }
}

// extends 继承: 只支持单继承，不支持多继承
class MySql extends Database {
  parseUrl() {
    return this.url.split(":")[0];
  }
}

// TS 中可以使用 implements 关键字来实现接口
interface Query {
  findMany(sql: string, params: any[]): any[];
  findOne(sql: string, params: any[]): any;
}

// MySQL Query 类实现 Query 接口
class MySqlQuery implements Query {
  findMany(sql: string, params: any[]): any[] {
    return [];
  }
  findOne(sql: string, params: any[]): any {
    return {};
  }
}

// TS 添加了对抽象类的支持，使用 abstract 关键字来定义抽象类
abstract class Animal {
  abstract name: string;
  abstract eat(): void;
}

class Dog extends Animal {
  name = "dog";
  eat() {
    console.log("dog eat");
  }
}
